package alingrad.engine.core;

import java.util.LinkedList;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import alingrad.engine.graphics.RenderListNode;
import alingrad.engine.util.GLColor;
import android.opengl.GLSurfaceView;
import android.util.Log;

public class GameRenderer implements GLSurfaceView.Renderer {
	private boolean mRenderListChanged;
	private LinkedList<RenderListNode> mRenderList;
	private Object mListLock = new Object();
	private Game mGame;

	private GLColor mBGColor;
	private boolean mColorChanged;
	public Object mColorLock = new Object();

	public GameRenderer(Game game) {
		mGame = game;
		mColorChanged = false;
		mRenderListChanged = true;
		mRenderList = new LinkedList<RenderListNode>();
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		synchronized(mListLock) {
			if (!mRenderListChanged) {
				while (!mRenderListChanged) {
					try {
						mListLock.wait();
					} catch (InterruptedException ex) {
					}
				}
			}
			mRenderListChanged = false;
		}

		synchronized(mColorLock) {
			if (mColorChanged) {
				gl.glClearColor(mBGColor.mRed, mBGColor.mGreen, mBGColor.mBlue, mBGColor.mAlpha);
				mColorChanged = false;
			}
		}

		synchronized(this) {
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

			for (RenderListNode object : mRenderList)
				object.draw(gl);
		}
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0, GameProperties.WIDTH, 0, GameProperties.HEIGHT, 1, 25);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
        Log.i(this.getClass().getName(), "Screen Size: " + width + ", " + height);
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

		//Sets up openGL settings
		gl.glEnable(GL10.GL_TEXTURE_2D);
		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glShadeModel(GL10.GL_FLAT);
		gl.glDisable(GL10.GL_DITHER);
		gl.glDisable(GL10.GL_LIGHTING);
		gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);

		gl.glFrontFace(GL10.GL_CCW);
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glCullFace(GL10.GL_BACK);

		gl.glClearColor(GameProperties.DEFAULT_BACKGROUND_COLOR.mRed,
				GameProperties.DEFAULT_BACKGROUND_COLOR.mGreen,
				GameProperties.DEFAULT_BACKGROUND_COLOR.mBlue,
				GameProperties.DEFAULT_BACKGROUND_COLOR.mAlpha);
		while (!mGame.isLoaded()) {
		}
		mGame.loadGraphics(this, gl);
	}

	public void setBackgroundColor(final GLColor color) {
		synchronized(mColorLock) {
			mBGColor = color;
			mColorChanged = true;
		}
	}

	public synchronized void setRenderList(final LinkedList<RenderListNode> renderList) {
		synchronized (mListLock) {
			mRenderList = renderList;
			mRenderListChanged = true;
			mListLock.notify();
		}
	}
}
